package com.sc.nft.admin.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.sc.nft.admin.request.*;
import com.sc.nft.annotation.SysMemberLogin;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.AccountStatusEnum;
import com.sc.nft.enums.WalletChannelEnum;
import com.sc.nft.helper.HfPayHelper;
import com.sc.nft.helper.LlPayHelper;
import com.sc.nft.helper.SandAccountHelper;
import com.sc.nft.service.LlUserExtService;
import com.sc.nft.service.SandTransferRecordService;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/sand")
@Api(tags = "用户钱包")
public class SandAccountAdminController {
    private final SandTransferRecordDao sandTransferRecordDao;
    private final SandWithdrawRecordDao sandWithdrawRecordDao;
    private final SandTransferRecordService sandTransferRecordService;
    private final WithdrawBankCardDao withdrawBankCardDao;
    private final HfPayHelper hfPayHelper;
    private final UserHfExtDao userHfExtDao;
    private final IdcardInfoDao idcardInfoDao;
    private final LlUserExtService llUserExtService;
    private final LlPayHelper llPayHelper;

    private final SandAccountHelper sandAccountHelper;
    private final UserInfoDao userInfoDao;

    @PostMapping(value = "/page", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "转账列表", notes = "转账列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<SandTransferRecordVO> page(@Valid @RequestBody SandTransferRequest request) {
        if (StrUtil.isNotBlank(request.getPhone())) {
            UserInfo userInfo = userInfoDao.getOneByUserTel(request.getPhone());
            if (ObjectUtil.isNull(userInfo)) {
                return PageResult.success(new Page<>(request.getPageNo(), request.getPageNo()));
            }
            request.setUserId(userInfo.getId());
        }
        Page page = sandTransferRecordDao.adminPage(request.getChannel(), request.getUserId(), request.getOrderNo(), request.getStartTime(), request.getEndTime(), request.getApprovalStatus(), request.getWithdrawStatus(), request.getPageNo(), request.getPageSize());

        List<SandTransferRecordVO> list = Lists.newArrayList();

        for (Object record : page.getRecords()) {
            SandTransferRecordVO vo = BeanUtil.toBean(record, SandTransferRecordVO.class);
            vo.setPhone(userInfoDao.getById(vo.getUserId()).getUserTel());
            IdcardInfo byUserIdAndIsPass = idcardInfoDao.getByUserIdAndIsPass(vo.getUserId());
            if (ObjectUtil.isNotNull(byUserIdAndIsPass)) {
                vo.setName(byUserIdAndIsPass.getName());
            }
            list.add(vo);
        }
        page.setRecords(list);

        return PageResult.success(page);
    }


    @PostMapping(value = "/sandAccountDetail", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "衫德钱包账户明细", notes = "衫德钱包账户明细", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result sandAccountDetail(@Valid @RequestBody SandAccountDetailRequest request) {

        return PageResult.success(sandAccountHelper.queryAccountDetail(userInfoDao.getOneByUserTel(request.getPhone()),
                DateUtil.format(request.getStartTime(), "yyyyMMdd"),
                DateUtil.format(request.getEndTime(), "yyyyMMdd"), request.getPageNo(), "10", null));
    }


    @PostMapping(value = "/hfRecord", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "汇付交易流水", notes = "汇付交易流水", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<HfTransferRecordVO> page(@Valid @RequestBody HfTransferRequest request) {
        UserHfExt userHfExt = null;
        if (StrUtil.isNotBlank(request.getPhone())) {
            UserInfo userInfo = userInfoDao.getOneByUserTel(request.getPhone());
            if (ObjectUtil.isNull(userInfo)) {
                return PageResult.success(new Page<>(request.getPageNo(), request.getPageNo()));
            }
            userHfExt = userHfExtDao.findByUserId(userInfo.getId());
            if (ObjectUtil.isNull(userHfExt) || userHfExt.getStatus() != AccountStatusEnum.SUCCESS) {
                return PageResult.fail("用户未完成汇付开户");
            }
        }
        JSONObject records = hfPayHelper.record(userHfExt, DateUtil.format(request.getStartTime(), "yyyyMMdd"), DateUtil.format(request.getEndTime(), "yyyyMMdd"), request.getPageNo(), request.getPageSize());
        Page<HfTransferRecordVO> page = new Page<>(request.getPageNo(), request.getPageSize(), records.getLong("total_count"));
        List<HfTransferRecordVO> result = Lists.newArrayList();
        JSONArray acct_logs = records.getJSONArray("acct_logs");
        for (int i = 0; i < acct_logs.size(); i++) {
            JSONObject record = acct_logs.getJSONObject(i);
            HfTransferRecordVO hfTransferRecordVO = record.toJavaObject(HfTransferRecordVO.class);
            result.add(hfTransferRecordVO);
        }
        page.setRecords(result);
        return PageResult.success(page);
    }

    @PostMapping(value = "/pass", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "审批通过", notes = "审批通过", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result pass(@Valid @RequestBody IdRequest request) {
        SandTransferRecord sandTransferRecord = sandTransferRecordDao.getById(request.getId());
        if (ObjectUtil.isNull(sandTransferRecord)) {
            return Result.fail("未找到提现记录");
        }
        if (sandTransferRecord.getApprovalStatus() != 0) {
            return Result.fail("审批状态不正确");
        }
        if (sandTransferRecord.getChannel() == WalletChannelEnum.HF) {
            sandAccountHelper.hfTransfer(userInfoDao.getById(sandTransferRecord.getUserId()), sandTransferRecord);
        } else {
            sandAccountHelper.transfer(userInfoDao.getById(sandTransferRecord.getUserId()), sandTransferRecord);
        }
        return Result.success();
    }


    @PostMapping(value = "/batchPass", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "批量审批通过", notes = "批量审批通过", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result batchPass(@Valid @RequestBody IdsRequest request) {
        for (Long id : request.getIds()) {
            SandTransferRecord sandTransferRecord = sandTransferRecordDao.getById(id);
            if (ObjectUtil.isNull(sandTransferRecord)) {
                return Result.fail(id + "：未找到提现记录");
            }
            if (sandTransferRecord.getApprovalStatus() != 0) {
                return Result.fail(id + "：审批状态不正确");
            }
            if (sandTransferRecord.getChannel() == WalletChannelEnum.HF) {
                sandAccountHelper.hfTransfer(userInfoDao.getById(sandTransferRecord.getUserId()), sandTransferRecord);
            } else {
                sandAccountHelper.transfer(userInfoDao.getById(sandTransferRecord.getUserId()), sandTransferRecord);
            }
        }

        return Result.success();
    }


    @PostMapping(value = "/back", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "退费", notes = "退费", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result back(@Valid @RequestBody BackRequest request) {
        SandTransferRecord sandTransferRecord = sandTransferRecordDao.getById(request.getId());
        if (ObjectUtil.isNull(sandTransferRecord)) {
            return Result.fail("未找到提现记录");
        }
        if (sandTransferRecord.getApprovalStatus() != 0) {
            return Result.fail("审批状态不正确");
        }
        if (StrUtil.isNotBlank(request.getRemark())) {
            sandTransferRecord.setRemark(request.getRemark());
        }
        sandTransferRecordService.backAmount(sandTransferRecord);
        return Result.success();
    }

    @PostMapping(value = "/updateRemark", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "修改失败原因", notes = "修改失败原因", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result back(@Valid @RequestBody BatchBackRequest request) {
        for (Long id : request.getIds()) {
            SandTransferRecord sandTransferRecord = sandTransferRecordDao.getById(id);
            if (ObjectUtil.isNull(sandTransferRecord)) {
                return Result.fail(id + ":未找到提现记录");
            }
            if (StrUtil.isNotBlank(request.getRemark())) {
                sandTransferRecord.setRemark(request.getRemark());
            }
            sandTransferRecord.updateById();
        }
        return Result.success();
    }


    @PostMapping(value = "/batchBack", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "批量退费", notes = "批量退费", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result batchBack(@Valid @RequestBody BatchBackRequest request) {
        for (Long id : request.getIds()) {
            SandTransferRecord sandTransferRecord = sandTransferRecordDao.getById(id);
            if (ObjectUtil.isNull(sandTransferRecord)) {
                return Result.fail(id + ":未找到提现记录");
            }
            if (sandTransferRecord.getApprovalStatus() != 0) {
                return Result.fail(id + ":审批状态不正确");
            }
            if (StrUtil.isNotBlank(request.getRemark())) {
                sandTransferRecord.setRemark(request.getRemark());
            }
            sandTransferRecordService.backAmount(sandTransferRecord);
        }
        return Result.success();
    }

    @PostMapping(value = "/getSandBalance", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "查询用户衫德钱包余额", notes = "批量退费", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<BalanceVO> getSandBalance(@Valid @RequestBody IdRequest request) {
        UserInfo userInfo = userInfoDao.getById(request.getId());
        BalanceVO balance = null;
        if (userInfo.getSandAccountOpen()) {
            balance = sandAccountHelper.getBalance(userInfo);
        } else {
            balance = new BalanceVO();
            balance.setAvailableBal(BigDecimal.ZERO);
            balance.setAvailableBal(BigDecimal.ZERO);
        }
        UserHfExt userHfExt = userHfExtDao.findByUserId(userInfo.getId());
        if (ObjectUtil.isNull(userHfExt) || userHfExt.getStatus() != AccountStatusEnum.SUCCESS) {
            balance.setHfAvailableBal(BigDecimal.ZERO);
            balance.setHfAvailableBal(BigDecimal.ZERO);
        } else {
            JSONObject json = hfPayHelper.getBalance(userHfExt);
            balance.setHfAvailableBal(json.getBigDecimal("balance"));
            balance.setHfFrozenBal(json.getBigDecimal("freeze_balance"));
        }
        LlUserExt llUserExt = llUserExtService.getByUserId(userInfo.getId());
        if ((ObjectUtil.isNotNull(llUserExt) && llUserExt.getStatus() == AccountStatusEnum.SUCCESS)) {
            JSONObject jsonObject = llPayHelper.getBalance(llUserExt);
            balance.setLlAvailableBal(jsonObject.getBigDecimal("amt_balaval"));
            balance.setLlFrozenBal(jsonObject.getBigDecimal("amt_balfrz"));
        }
        return Result.success(balance);
    }


    @PostMapping(value = "/withdrawPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "提现列表", notes = "提现列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<SandWithdrawRecordVO> withdrawPage(@Valid @RequestBody SandWithdrawRequest request) {
        if (StrUtil.isNotBlank(request.getPhone())) {
            UserInfo userInfo = userInfoDao.getOneByUserTel(request.getPhone());
            if (ObjectUtil.isNull(userInfo)) {
                return PageResult.success(new Page<>(request.getPageNo(), request.getPageNo()));
            }
            request.setUserId(userInfo.getId());
        }
        String relationCardNo = null;
        if (StrUtil.isNotBlank(request.getBankCardNo())) {
            WithdrawBankCard withdrawBankCard = withdrawBankCardDao.findByCard(request.getBankCardNo());
            if (ObjectUtil.isNull(withdrawBankCard)) {
                return PageResult.success(new Page<>(request.getPageNo(), request.getPageNo()));
            }
            relationCardNo = withdrawBankCard.getRelatedCardNo();
        }

        Page page = sandWithdrawRecordDao.adminPage(request.getUserId(), request.getStatus(), request.getOrderNo(), request.getStartTime(), request.getEndTime(), relationCardNo, request.getPageNo(), request.getPageSize());

        List<SandWithdrawRecordVO> list = Lists.newArrayList();

        for (Object record : page.getRecords()) {
            SandWithdrawRecordVO vo = BeanUtil.toBean(record, SandWithdrawRecordVO.class);
            vo.setPhone(userInfoDao.getById(vo.getUserId()).getUserTel());
            list.add(vo);
        }
        page.setRecords(list);
        return PageResult.success(page);
    }

    @PostMapping(value = "/MoneyRiskAdminPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "资金风控表", notes = "资金风控表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<MoneyRiskPageVO> moneyRiskAdminPage(@RequestBody MoneyRiskRequest request) {
        Long userId = null;
        if (StrUtil.isNotBlank(request.getUserTel())) {
            UserInfo userInfo = userInfoDao.getOneByUserTel(request.getUserTel());
            if (ObjectUtil.isNull(userInfo)) {
                return PageResult.success();
            }
            userId = userInfo.getId();
        }
        return PageResult.success(sandWithdrawRecordDao.moneyRiskAdminPage(userId, request.getName(), request.getPageNo(), request.getPageSize()));
    }
}
